﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace BankOCR
{
    public class DigitalSymbol
    {
        private char[,] _face;
        public DigitalSymbol(char[,] face)
        {
            if (face.GetLength(0) != 3 || face.GetLength(1) != 3)
                throw new InvalidOperationException("DigitalSymbol has to be 3x3.");
            this._face = face;
        }

        public DigitalSymbol(DigitalSymbol symbol) : this((char[,])symbol._face.Clone()) { }

        public char this[int row, int column]
        {
            get { return _face[row, column]; }
            set { _face[row, column] = value; }
        }

        public DigitalSymbol ToggleCharAt(int row, int col)
        {
            var charWhenActive = col == 1 ? '_' : '|';
            this[row, col] = this[row, col] == ' ' ? charWhenActive : ' ';
            return this;
        }

        public override int GetHashCode()
        {
            return _face.Cast<char>().Select((@char, index) => @char != ' ' ? (int)Math.Pow(2, index) : 0).Sum();
        }

        public override bool Equals(object obj)
        {
            var other = obj as DigitalSymbol;
            return other != null ? this.GetHashCode() == other.GetHashCode() : false;
        }

        public override string ToString()
        {
            return new string(new[] {
                _face[0, 0], _face[0, 1], _face[0, 2], '\n',
                _face[1, 0], _face[1, 1], _face[1, 2], '\n',
                _face[2, 0], _face[2, 1], _face[2, 2], '\n'});
        }

        #region SpecificSymbols

        public static IEnumerable<DigitalSymbol> AllKnownSymbols = new[] {
            DigitalSymbol.Zero, DigitalSymbol.One, DigitalSymbol.Two, DigitalSymbol.Three, 
            DigitalSymbol.Four, DigitalSymbol.Five, DigitalSymbol.Six, DigitalSymbol.Seven, 
            DigitalSymbol.Eight, DigitalSymbol.Nine };

        public static DigitalSymbol Zero
        {
            get
            {
                return new DigitalSymbol(new[,]{
                    {' ', '_', ' '},
                    {'|', ' ', '|'},
                    {'|', '_', '|'}
                });
            }
        }

        public static DigitalSymbol One
        {
            get
            {
                return new DigitalSymbol(new[,]{
                    {' ', ' ', ' '},
                    {' ', ' ', '|'},
                    {' ', ' ', '|'}
                });
            }
        }

        public static DigitalSymbol Two
        {
            get
            {
                return new DigitalSymbol(new[,]{
                    {' ', '_', ' '},
                    {' ', '_', '|'},
                    {'|', '_', ' '}
                });
            }
        }

        public static DigitalSymbol Three
        {
            get
            {
                return new DigitalSymbol(new[,]{
                    {' ', '_', ' '},
                    {' ', '_', '|'},
                    {' ', '_', '|'}
                });
            }
        }

        public static DigitalSymbol Four
        {
            get
            {
                return new DigitalSymbol(new[,]{
                    {' ', ' ', ' '},
                    {'|', '_', '|'},
                    {' ', ' ', '|'}
                });
            }
        }

        public static DigitalSymbol Five
        {
            get
            {
                return new DigitalSymbol(new[,]{
                    {' ', '_', ' '},
                    {'|', '_', ' '},
                    {' ', '_', '|'}
                });
            }
        }

        public static DigitalSymbol Six
        {
            get
            {
                return new DigitalSymbol(new[,]{
                    {' ', '_', ' '},
                    {'|', '_', ' '},
                    {'|', '_', '|'}
                });
            }
        }

        public static DigitalSymbol Seven
        {
            get
            {
                return new DigitalSymbol(new[,]{
                    {' ', '_', ' '},
                    {' ', ' ', '|'},
                    {' ', ' ', '|'}
                });
            }
        }

        public static DigitalSymbol Eight
        {
            get
            {
                return new DigitalSymbol(new[,]{
                    {' ', '_', ' '},
                    {'|', '_', '|'},
                    {'|', '_', '|'}
                });
            }
        }

        public static DigitalSymbol Nine
        {
            get
            {
                return new DigitalSymbol(new[,]{
                    {' ', '_', ' '},
                    {'|', '_', '|'},
                    {' ', '_', '|'}
                });
            }
        }

        #endregion
    }
}
